home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / Mesa-3.0 / SRC / Windows / wmesaOld.c < prev   
Encoding:
C/C++ Source or Header  |  1997-09-01  |  71.8 KB  |  2,733 lines

  1. /*
  2.  *    File name    :    wmesa.c
  3.  *  Version        :    2.3
  4.  *
  5.  *  Display driver for Mesa 2.3  under 
  6.  *    Windows95 and WindowsNT
  7.  *
  8.  *    Copyright (C) 1996-  Li Wei
  9.  *  Address        :        Institute of Artificial Intelligence
  10.  *                :            & Robotics
  11.  *                :        Xi'an Jiaotong University
  12.  *  Email        :        liwei@aiar.xjtu.edu.cn
  13.  *  Web page    :        http://sun.aiar.xjtu.edu.cn
  14.  *
  15.  *  This file and its associations are partially borrowed from the 
  16.  *  Windows NT driver for Mesa 1.8 , written by Mark Leaming
  17.  *  (mark@rsinc.com).
  18.  */
  19.  
  20.  
  21. /*
  22.  * $Log: ddmesa.c,v $
  23.  * Revision 1.0  1997/06/14 17:51:00 CST by Li Wei(liwei@aiar.xjtu.edu.cn)
  24.  * New display driver for Mesa 2.x using Microsoft Direct Draw
  25.  * Initial vision
  26.  */
  27.  
  28.  
  29. #define WMESA_STEREO_C
  30.  
  31. #include <windows.h>
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <GL/wmesa.h>
  35. #include "wmesadef.h"
  36. #include "context.h"
  37. #include "dd.h"
  38. #include "xform.h"
  39. #include "vb.h"
  40. #include "matrix.h"
  41. #include "depth.h"
  42.  
  43. #ifdef PROFILE
  44. //    #include "profile.h"
  45. #endif
  46.  
  47. #ifdef DITHER
  48.     #include <wing.h>
  49. #endif
  50.  
  51. #ifdef __CYGWIN32__
  52. #include "macros.h"
  53. #include <string.h>
  54. #define CopyMemory memcpy
  55. #endif
  56. #include "mesa_extend.h"
  57. #include "colors.h"
  58.  
  59. #if !defined(NO_STEREO)
  60.     
  61.     #include "gl\glu.h"
  62.     #include "stereo.h"
  63.  
  64. #endif
  65. #if !defined(NO_PARALLEL)
  66. //    #include "parallel.h"
  67. #endif
  68.  
  69. struct DISPLAY_OPTIONS displayOptions;
  70.  
  71. GLenum stereoCompile = GL_FALSE ;
  72. GLenum stereoShowing  = GL_FALSE ;
  73. GLenum stereoBuffer = GL_FALSE;
  74. #if !defined(NO_STEREO)
  75. GLint displayList = MAXIMUM_DISPLAY_LIST ;
  76. #endif
  77. GLint stereo_flag = 0 ;
  78.  
  79. /* end of added code*/
  80.  
  81. static PWMC Current = NULL;
  82. WMesaContext WC = NULL;
  83.  
  84. #ifdef NDEBUG
  85.   #define assert(ignore)    ((void) 0)
  86. #else
  87.   void Mesa_Assert(void *Cond,void *File,unsigned Line)
  88.   {
  89.     char Msg[512];
  90.     sprintf(Msg,"%s %s %d",Cond,File,Line);
  91.     MessageBox(NULL,Msg,"Assertion failed.",MB_OK);
  92.     exit(1);
  93.   }
  94.   #define assert(e)    if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
  95. #endif
  96.  
  97. //#define DD_GETDC (Current->hDC )
  98. #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
  99. //#define DD_GETDC ((Current->db_flag) ? Current->hDCPrimary : Current->hDCBack )
  100. #define DD_RELEASEDC
  101.  
  102. //#define BEGINGDICALL    if(Current->rgb_flag)wmFlushBits(Current);
  103. #define BEGINGDICALL
  104. //#define ENDGDICALL        if(Current->rgb_flag)wmGetBits(Current);
  105. #define ENDGDICALL
  106.  
  107. //#define FLIP(Y)  (Current->dither_flag? Y : Current->height-(Y)-1)
  108. //#define FLIP(Y)  (Current->height-(Y)-1)
  109. //#define FLIP(Y) Y
  110. #define FLIP(Y)  (Current->db_flag? Y: Current->height-(Y)-1)
  111. #define STARTPROFILE 
  112. #define ENDPROFILE(PARA) 
  113.  
  114. #define DITHER_RGB_TO_8BIT_SETUP            \
  115.         GLubyte pixelDithered;
  116.  
  117. #define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline)                \
  118. {                                                                            \
  119.     char unsigned redtemp, greentemp, bluetemp, paletteindex;                \
  120.     redtemp = aDividedBy51[red]                                                \
  121.           + (aModulo51[red] > aHalftone8x8[(pixel%8)*8                        \
  122.           + scanline%8]);                                                    \
  123.     greentemp = aDividedBy51[(char unsigned)green]                            \
  124.           + (aModulo51[green] > aHalftone8x8[                                \
  125.           (pixel%8)*8 + scanline%8]);                                        \
  126.     bluetemp = aDividedBy51[(char unsigned)blue]                            \
  127.           + (aModulo51[blue] > aHalftone8x8[                                \
  128.           (pixel%8)*8 +scanline%8]);                                        \
  129.     paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp];        \
  130.     pixelDithered = aWinGHalftoneTranslation[paletteindex];                    \
  131. }
  132.  
  133.  
  134. #ifdef DDRAW
  135.     static BOOL DDInit( WMesaContext wc, HWND hwnd);
  136.     static void DDFree( WMesaContext wc);
  137.     static HRESULT DDRestoreAll( WMesaContext wc );
  138.     static void DDDeleteOffScreen(WMesaContext wc);
  139.     static BOOL DDCreateOffScreen(WMesaContext wc);
  140. #endif
  141.  
  142. static void FlushToFile(PWMC pwc, PSTR    szFile);
  143.  
  144. BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize);
  145. BOOL wmDeleteBackingStore(PWMC pwc);
  146. void wmCreatePalette( PWMC pwdc );
  147. BOOL wmSetDibColors(PWMC pwc);
  148. void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b);
  149.  
  150. void wmCreateDIBSection(
  151.     HDC     hDC,
  152.     PWMC pwc,    // handle of device context
  153.     CONST BITMAPINFO *pbmi,    // address of structure containing bitmap size, format, and color data
  154.     UINT iUsage    // color data type indicator: RGB values or palette indices
  155.     );
  156.  
  157.  
  158. void WMesaViewport( GLcontext *ctx,
  159.                   GLint x, GLint y, GLsizei width, GLsizei height );
  160.  
  161. static triangle_func choose_triangle_function( GLcontext *ctx );
  162.  
  163. static void wmSetPixelFormat( PWMC wc, HDC hDC)
  164. {
  165.     if(wc->rgb_flag)
  166.         wc->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);
  167.     else
  168.         wc->cColorBits = 8;
  169.     switch(wc->cColorBits){
  170.         case 8:
  171.             if(wc->dither_flag != GL_TRUE)
  172.                 wc->pixelformat = PF_INDEX8;
  173.             else
  174.                 wc->pixelformat = PF_DITHER8;
  175.             break;
  176.         case 16:
  177.             wc->pixelformat = PF_5R6G5B;
  178.             break;
  179.         case 32:
  180.             wc->pixelformat = PF_8R8G8B;
  181.             break;
  182.         default:
  183.             wc->pixelformat = PF_BADFORMAT;
  184.     }
  185. }
  186.  
  187. //
  188. // This function sets the color table of a DIB section
  189. // to match that of the destination DC
  190. //
  191. BOOL /*WINAPI*/ wmSetDibColors(PWMC pwc)
  192. {
  193.     RGBQUAD            *pColTab, *pRGB;
  194.     PALETTEENTRY    *pPal, *pPE;
  195.     int                i, nColors;
  196.     BOOL            bRet=TRUE;
  197.     DWORD            dwErr=0;
  198.  
  199.     /* Build a color table in the DIB that maps to the
  200.        selected palette in the DC.
  201.     */
  202.     nColors = 1 << pwc->cColorBits;
  203.     pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY));
  204.     memset( pPal, 0, nColors * sizeof(PALETTEENTRY) );
  205.     GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal );
  206.     pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD));
  207.     for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) {
  208.         pRGB->rgbRed = pPE->peRed;
  209.         pRGB->rgbGreen = pPE->peGreen;
  210.         pRGB->rgbBlue = pPE->peBlue;
  211.     }
  212.     if(pwc->db_flag)
  213.         bRet = SetDIBColorTable(pwc->dib.hDC, 0, nColors, pColTab );
  214.  
  215.     if(!bRet)
  216.         dwErr = GetLastError();
  217.  
  218.     free( pColTab );
  219.     free( pPal );
  220.  
  221.     return(bRet);
  222. }
  223.  
  224.  
  225. //
  226. // Free up the dib section that was created
  227. //
  228. BOOL wmDeleteBackingStore(PWMC pwc)
  229. {
  230.     SelectObject(pwc->dib.hDC, pwc->hOldBitmap);
  231.     DeleteDC(pwc->dib.hDC);
  232.     DeleteObject(pwc->hbmDIB);
  233.     UnmapViewOfFile(pwc->dib.base);
  234.     CloseHandle(pwc->dib.hFileMap);
  235.     return TRUE;
  236. }
  237.  
  238.  
  239. //
  240. // This function creates the DIB section that is used for combined
  241. // GL and GDI calls
  242. //
  243. BOOL /*WINAPI*/ wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)
  244. {
  245.     HDC hdc = pwc->hDC;
  246.     LPBITMAPINFO pbmi = &(pwc->bmi);
  247.     int        iUsage;
  248.  
  249.     pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  250.     pbmi->bmiHeader.biWidth = lxSize;
  251.     pbmi->bmiHeader.biHeight= -lySize;
  252.     pbmi->bmiHeader.biPlanes = 1;
  253.     if(pwc->rgb_flag)
  254.         pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL);
  255.     else
  256.         pbmi->bmiHeader.biBitCount = 8;
  257.     pbmi->bmiHeader.biCompression = BI_RGB;
  258.     pbmi->bmiHeader.biSizeImage = 0;
  259.     pbmi->bmiHeader.biXPelsPerMeter = 0;
  260.     pbmi->bmiHeader.biYPelsPerMeter = 0;
  261.     pbmi->bmiHeader.biClrUsed = 0;
  262.     pbmi->bmiHeader.biClrImportant = 0;
  263.  
  264.     iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS;
  265.  
  266.     pwc->cColorBits = pbmi->bmiHeader.biBitCount;
  267.     pwc->ScanWidth = pwc->pitch = lxSize;
  268.  
  269.     wmCreateDIBSection(hdc, pwc, pbmi, iUsage);
  270.  
  271.     if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) {
  272.         wmCreatePalette( pwc );
  273.         wmSetDibColors( pwc );
  274.     }
  275.     wmSetPixelFormat(pwc, pwc->hDC);
  276.     return(TRUE);
  277.  
  278. }
  279.  
  280.  
  281. //
  282. // This function copies one scan line in a DIB section to another
  283. //
  284. BOOL WINAPI wmSetDIBits(PWMC pwc, UINT uiScanWidth, UINT uiNumScans, UINT nBypp, UINT uiNewWidth, LPBYTE pBits)
  285. {
  286.     UINT uiScans = 0;
  287.     LPBYTE    pDest = pwc->pbPixels;
  288.     DWORD    dwNextScan = uiScanWidth;
  289.     DWORD    dwNewScan = uiNewWidth;
  290.     DWORD    dwScanWidth = (uiScanWidth * nBypp);
  291.  
  292.     //
  293.     // We need to round up to the nearest DWORD
  294.     // and multiply by the number of bytes per
  295.     // pixel
  296.     //
  297.     dwNextScan = (((dwNextScan * nBypp)+ 3) & ~3);
  298.     dwNewScan = (((dwNewScan * nBypp)+ 3) & ~3);
  299.  
  300.     for(uiScans = 0; uiScans < uiNumScans; uiScans++){
  301.         CopyMemory(pDest, pBits, dwScanWidth);
  302.         pBits += dwNextScan;
  303.         pDest += dwNewScan;
  304.     }
  305.  
  306.     return(TRUE);
  307.  
  308. }
  309.  
  310.  
  311. BOOL wmFlush(PWMC pwc);
  312.  
  313. /*
  314.  * Useful macros:
  315.    Modified from file osmesa.c     
  316.  */
  317.  
  318.  
  319. #define PIXELADDR(X,Y)  ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* Current->ScanWidth + (X)*nBypp)
  320. #define PIXELADDR1( X, Y )  \
  321.     ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))           
  322. #define PIXELADDR2( X, Y )  \
  323.     ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
  324. #define PIXELADDR4( X, Y )  \
  325.     ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4) 
  326.  
  327.  
  328. BYTE DITHER_RGB_2_8BIT( int r, int g, int b, int x, int y);
  329.  
  330. /* Finish all pending operations and synchronize. */
  331. static void finish(GLcontext* ctx)
  332. {
  333.  /* No op */
  334. }
  335.  
  336.  
  337. //
  338. // We cache all gl draw routines until a flush is made
  339. //
  340. static void flush(GLcontext* ctx)
  341. {
  342.     STARTPROFILE
  343.     if((Current->rgb_flag /*&& !(Current->dib.fFlushed)*/&&!(Current->db_flag))
  344.         ||(!Current->rgb_flag))
  345.     {
  346.         wmFlush(Current);
  347.     }
  348.     ENDPROFILE(flush)
  349.    
  350. }
  351.  
  352.  
  353.  
  354. /*
  355.  * Set the color index used to clear the color buffer.
  356.  */
  357. static void clear_index(GLcontext* ctx, GLuint index)
  358. {
  359.   STARTPROFILE
  360.   Current->clearpixel = index;
  361.   ENDPROFILE(clear_index)
  362. }
  363.  
  364.  
  365.  
  366. /*
  367.  * Set the color used to clear the color buffer.
  368.  */
  369. static void clear_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  370. {
  371.   STARTPROFILE
  372.   Current->clearpixel=RGB(r, g, b );
  373.   ENDPROFILE(clear_color)
  374. }
  375.  
  376.  
  377.  
  378. /*
  379.  * Clear the specified region of the color buffer using the clear color
  380.  * or index as specified by one of the two functions above.
  381.  */
  382. static void clear(GLcontext* ctx, 
  383.                   GLboolean all,GLint x, GLint y, GLint width, GLint height )
  384. {
  385.     DWORD    dwColor;    
  386.     WORD    wColor;
  387.     BYTE    bColor;
  388.     LPDWORD    lpdw = (LPDWORD)Current->pbPixels;
  389.     LPWORD    lpw = (LPWORD)Current->pbPixels;
  390.     LPBYTE    lpb = Current->pbPixels;
  391.     int        lines;
  392.  
  393.     STARTPROFILE
  394.  
  395.     if (all){
  396.         x=y=0;
  397.         width=Current->width;
  398.         height=Current->height;
  399.     }
  400.     if(Current->db_flag==GL_TRUE){
  401.         UINT    nBypp = Current->cColorBits / 8;
  402.         int        i = 0;
  403.         int        iSize;
  404.  
  405.         if(nBypp ==1 ){
  406.             /* Need rectification */
  407.             iSize = Current->width/4;
  408.             bColor  = BGR8(GetRValue(Current->clearpixel), 
  409.                            GetGValue(Current->clearpixel), 
  410.                            GetBValue(Current->clearpixel));
  411.             wColor  = MAKEWORD(bColor,bColor);
  412.             dwColor = MAKELONG(wColor, wColor);
  413.         }
  414.         if(nBypp == 2){
  415.             iSize = Current->width / 2;
  416.             wColor = BGR16(GetRValue(Current->clearpixel), 
  417.                            GetGValue(Current->clearpixel), 
  418.                            GetBValue(Current->clearpixel));
  419.             dwColor = MAKELONG(wColor, wColor);
  420.         }
  421.         else if(nBypp == 4){
  422.             iSize = Current->width;
  423.             dwColor = BGR32(GetRValue(Current->clearpixel), 
  424.                            GetGValue(Current->clearpixel), 
  425.                            GetBValue(Current->clearpixel));
  426.         }
  427.  
  428.         while(i < iSize){
  429.             *lpdw = dwColor;
  430.             lpdw++;
  431.             i++;
  432.         }
  433.  
  434.         //
  435.         // This is the 24bit case
  436.         //
  437.         if (nBypp == 3) {
  438.             iSize = Current->width *3/4;
  439.             dwColor = BGR24(GetRValue(Current->clearpixel), 
  440.                            GetGValue(Current->clearpixel), 
  441.                            GetBValue(Current->clearpixel));
  442.             while(i < iSize){
  443.                 *lpdw = dwColor;
  444.                 lpb += nBypp;
  445.                 lpdw = (LPDWORD)lpb;
  446.                 i++;
  447.             }
  448.         }
  449.  
  450.         i = 0;
  451.         if(stereo_flag) lines = height /2;
  452.         else lines = height;
  453.         do{
  454.             lpb += Current->ScanWidth;
  455.             memcpy(lpb, Current->pbPixels, iSize*4);
  456.             i++;
  457.         }
  458.         while(i<lines-1);
  459.     }
  460.     else{ // For single buffer
  461.          HDC DC=DD_GETDC;
  462.          HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
  463.          HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
  464.          HPEN Old_Pen=SelectObject(DC,Pen);
  465.          HBRUSH Old_Brush=SelectObject(DC,Brush);
  466.          Rectangle(DC,x,y,x+width,y+height);
  467.          SelectObject(DC,Old_Pen);
  468.          SelectObject(DC,Old_Brush);
  469.          DeleteObject(Pen);
  470.          DeleteObject(Brush);
  471.          DD_RELEASEDC;
  472.       }
  473.  
  474.  
  475.  
  476.     ENDPROFILE(clear)
  477. }
  478.  
  479.  
  480.  
  481. /* Set the current color index. */
  482. static void set_index(GLcontext* ctx, GLuint index)
  483. {
  484.   STARTPROFILE
  485.   Current->pixel=index;
  486.   ENDPROFILE(set_index)
  487. }
  488.  
  489.  
  490.  
  491. /* Set the current RGBA color. */
  492. static void set_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  493. {
  494.   STARTPROFILE
  495.   Current->pixel = RGB( r, g, b );
  496.   ENDPROFILE(set_color)
  497. }
  498.  
  499.  
  500.  
  501. /* Set the index mode bitplane mask. */
  502. static GLboolean index_mask(GLcontext* ctx, GLuint mask)
  503. {
  504.    /* can't implement */
  505.    return GL_FALSE;
  506. }
  507.  
  508.  
  509.  
  510. /* Set the RGBA drawing mask. */
  511. static GLboolean color_mask( GLcontext* ctx,
  512.                              GLboolean rmask, GLboolean gmask,
  513.                              GLboolean bmask, GLboolean amask)
  514. {
  515.    /* can't implement */
  516.    return GL_FALSE;
  517. }
  518.  
  519.  
  520.  
  521. /*
  522.  * Set the pixel logic operation.  Return GL_TRUE if the device driver
  523.  * can perform the operation, otherwise return GL_FALSE.  If GL_FALSE
  524.  * is returned, the logic op will be done in software by Mesa.
  525.  */
  526. GLboolean logicop( GLcontext* ctx, GLenum op )
  527. {
  528.    /* can't implement */
  529.    return GL_FALSE;
  530. }
  531.  
  532.  
  533. static void dither( GLcontext* ctx, GLboolean enable )
  534. {
  535.     if(enable == GL_FALSE){
  536.        Current->dither_flag = GL_FALSE;
  537.        if(Current->cColorBits == 8)
  538.            Current->pixelformat = PF_INDEX8;        
  539.    }
  540.    else{
  541.        if (Current->rgb_flag && Current->cColorBits == 8){
  542.            Current->pixelformat = PF_DITHER8;
  543.            Current->dither_flag = GL_TRUE;
  544.        }
  545.        else
  546.            Current->dither_flag = GL_FALSE;
  547.    }
  548. }
  549.  
  550.  
  551.  
  552. static GLboolean set_buffer( GLcontext* ctx, GLenum mode )
  553. {
  554.    STARTPROFILE
  555.    /* TODO: this could be better */
  556.    if (mode==GL_FRONT || mode==GL_BACK) {
  557.       return GL_TRUE;
  558.    }
  559.    else {
  560.       return GL_FALSE;
  561.    }
  562.    ENDPROFILE(set_buffer)
  563. }
  564.  
  565.  
  566.  
  567. /* Return characteristics of the output buffer. */
  568. static void buffer_size( GLcontext* ctx, GLuint *width, GLuint *height /*, GLuint *depth */)
  569. {
  570.     
  571.     int New_Size;
  572.     RECT CR;
  573.     
  574.     STARTPROFILE
  575.     GetClientRect(Current->Window,&CR);
  576.  
  577.     *width=CR.right;
  578.     *height=CR.bottom;
  579. //    *depth = Current->depth;
  580.  
  581.     New_Size=((*width)!=Current->width) || ((*height)!=Current->height);
  582.  
  583.     if (New_Size){
  584.         Current->width=*width;
  585.         Current->height=*height;
  586.         Current->ScanWidth=Current->width;
  587.         if ((Current->ScanWidth%sizeof(long))!=0)
  588.             Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
  589.  
  590.         if (Current->db_flag){
  591. #ifdef DDRAW
  592.             DDDeleteOffScreen(Current);
  593.             DDCreateOffScreen(Current);
  594. #else
  595.         if (Current->rgb_flag==GL_TRUE && Current->dither_flag!=GL_TRUE){
  596.                 wmDeleteBackingStore(Current);
  597.                 wmCreateBackingStore(Current, Current->width, Current->height);
  598.             }
  599. #endif
  600.             }
  601.  
  602. //    Resize OsmesaBuffer if in Parallel mode
  603. #if !defined(NO_PARALLEL)    
  604.             if(parallelFlag)
  605.             PRSizeRenderBuffer(Current->width, Current->height,Current->ScanWidth,
  606.             Current->rgb_flag == GL_TRUE ? Current->pbPixels: Current->ScreenMem);
  607. #endif
  608.         }
  609.    ENDPROFILE(buffer_size)
  610. }
  611.  
  612.  
  613.  
  614. /**********************************************************************/
  615. /*****           Accelerated point, line, polygon rendering       *****/
  616. /**********************************************************************/
  617.  
  618.  
  619. static void fast_rgb_points( GLcontext* ctx, GLuint first, GLuint last )
  620. {
  621.    GLuint i;
  622.  //  HDC DC=DD_GETDC;
  623.     PWMC    pwc = Current;
  624.      
  625.     STARTPROFILE
  626.  
  627.     if (Current->gl_ctx->VB->MonoColor) {
  628.       /* all drawn with current color */
  629.       for (i=first;i<=last;i++) {
  630.          if (!Current->gl_ctx->VB->ClipMask[i]) {
  631.             int x, y;
  632.             x =       (GLint) Current->gl_ctx->VB->Win[i][0];
  633.             y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );
  634.             wmSetPixel(pwc, y,x,GetRValue(Current->pixel), 
  635.                         GetGValue(Current->pixel), GetBValue(Current->pixel));
  636.          }
  637.       }
  638.    }
  639.    else {
  640.       /* draw points of different colors */
  641.       for (i=first;i<=last;i++) {
  642.          if (!Current->gl_ctx->VB->ClipMask[i]) {
  643.             int x, y;
  644.             unsigned long pixel=RGB(Current->gl_ctx->VB->Color[i][0]*255.0,
  645.                                     Current->gl_ctx->VB->Color[i][1]*255.0,
  646.                                     Current->gl_ctx->VB->Color[i][2]*255.0);
  647.             x =       (GLint) Current->gl_ctx->VB->Win[i][0];
  648.             y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );
  649.             wmSetPixel(pwc, y,x,Current->gl_ctx->VB->Color[i][0]*255.0, 
  650.                                     Current->gl_ctx->VB->Color[i][1]*255.0,
  651.                                     Current->gl_ctx->VB->Color[i][2]*255.0);
  652.          }
  653.       }
  654.    }
  655. //   DD_RELEASEDC;
  656.    ENDPROFILE(fast_rgb_points)
  657. }
  658.  
  659.  
  660.  
  661. /* Return pointer to accerated points function */
  662. extern points_func choose_points_function( GLcontext* ctx )
  663. {
  664.    STARTPROFILE
  665.    if (ctx->Point.Size==1.0 && !ctx->Point.SmoothFlag && ctx->RasterMask==0
  666.        && !ctx->Texture.Enabled  && ctx->Visual->RGBAflag) {
  667.    ENDPROFILE(choose_points_function)
  668.       return fast_rgb_points;
  669.    }
  670.    else {
  671.    ENDPROFILE(choose_points_function)
  672.       return NULL;
  673.    }
  674. }
  675.  
  676.  
  677.  
  678. /* Draw a line using the color specified by Current->gl_ctx->VB->Color[pv] */
  679. static void fast_flat_rgb_line( GLcontext* ctx, GLuint v0, GLuint v1, GLuint pv )
  680. {
  681.     STARTPROFILE
  682.     int x0, y0, x1, y1;
  683.     unsigned long pixel;
  684.     HDC DC=DD_GETDC;
  685.     HPEN Pen;
  686.     HPEN Old_Pen;
  687.  
  688.     if (Current->gl_ctx->VB->MonoColor) {
  689.       pixel = Current->pixel;  /* use current color */
  690.     }
  691.     else {
  692.       pixel = RGB(Current->gl_ctx->VB->Color[pv][0]*255.0, Current->gl_ctx->VB->Color[pv][1]*255.0, Current->gl_ctx->VB->Color[pv][2]*255.0);
  693.     }
  694.  
  695.     x0 =       (int) Current->gl_ctx->VB->Win[v0][0];
  696.     y0 = FLIP( (int) Current->gl_ctx->VB->Win[v0][1] );
  697.     x1 =       (int) Current->gl_ctx->VB->Win[v1][0];
  698.     y1 = FLIP( (int) Current->gl_ctx->VB->Win[v1][1] );
  699.  
  700.  
  701.     BEGINGDICALL
  702.  
  703.     Pen=CreatePen(PS_SOLID,1,pixel);
  704.     Old_Pen=SelectObject(DC,Pen);
  705.     MoveToEx(DC,x0,y0,NULL);
  706.     LineTo(DC,x1,y1);
  707.     SelectObject(DC,Old_Pen);
  708.     DeleteObject(Pen);
  709.     DD_RELEASEDC;
  710.  
  711.     ENDGDICALL
  712.  
  713.     ENDPROFILE(fast_flat_rgb_line)
  714. }
  715.  
  716.  
  717.  
  718. /* Return pointer to accerated line function */
  719. static line_func choose_line_function( GLcontext* ctx )
  720. {
  721.     STARTPROFILE
  722.    if (ctx->Line.Width==1.0 && !ctx->Line.SmoothFlag && !ctx->Line.StippleFlag
  723.        && ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0
  724.        && !ctx->Texture.Enabled && Current->rgb_flag) {
  725.    ENDPROFILE(choose_line_function)
  726.       return fast_flat_rgb_line;
  727.    }
  728.    else {
  729.    ENDPROFILE(choose_line_function)
  730.       return NULL;
  731.    }
  732. }
  733.  
  734.  
  735. /**********************************************************************/
  736. /*****                 Span-based pixel drawing                   *****/
  737. /**********************************************************************/
  738.  
  739.  
  740. /* Write a horizontal span of color-index pixels with a boolean mask. */
  741. static void write_index_span( GLcontext* ctx, 
  742.                               GLuint n, GLint x, GLint y,
  743.                               const GLuint index[],
  744.                               const GLubyte mask[] )
  745. {
  746.       STARTPROFILE
  747.       GLuint i;
  748.       PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
  749.       assert(Current->rgb_flag==GL_FALSE);
  750.       for (i=0; i<n; i++)
  751.         if (mask[i])
  752.           Mem[i]=index[i];
  753.        ENDPROFILE(write_index_span)
  754. }
  755.  
  756.  
  757.  
  758. /*
  759.  * Write a horizontal span of pixels with a boolean mask.  The current
  760.  * color index is used for all pixels.
  761.  */
  762. static void write_monoindex_span(GLcontext* ctx, 
  763.                                  GLuint n,GLint x,GLint y,
  764.                                  const GLubyte mask[])
  765. {
  766.       STARTPROFILE
  767.       GLuint i;
  768.       BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
  769.       assert(Current->rgb_flag==GL_FALSE);
  770.       for (i=0; i<n; i++)
  771.         if (mask[i])
  772.           Mem[i]=Current->pixel;
  773.       ENDPROFILE(write_monoindex_span)
  774. }
  775.  
  776. /*
  777.     To improve the performance of this routine, frob the data into an actual scanline
  778.     and call bitblt on the complete scan line instead of SetPixel.
  779. */
  780.  
  781. /* Write a horizontal span of color pixels with a boolean mask. */
  782. static void write_color_span( GLcontext* ctx, 
  783.               GLuint n, GLint x, GLint y,
  784.               const GLubyte
  785.               red[], const GLubyte green[],
  786.               const GLubyte blue[], const GLubyte alpha[],
  787.               const GLubyte mask[] )
  788. {
  789.     STARTPROFILE
  790.  
  791.     PWMC    pwc = Current;
  792.  
  793.     if (pwc->rgb_flag==GL_TRUE)
  794.     {
  795.         GLuint i;
  796.         HDC DC=DD_GETDC;
  797.         y=FLIP(y);
  798.  
  799.         if (mask) {
  800.             for (i=0; i<n; i++)
  801.                 if (mask[i])
  802.                     wmSetPixel(pwc, y, x + i,red[i], green[i], blue[i]);
  803.         }
  804.  
  805.         else {
  806.             for (i=0; i<n; i++)
  807.                 wmSetPixel(pwc, y, x + i, red[i], green[i], blue[i]);
  808.         }
  809.  
  810.         DD_RELEASEDC;
  811.  
  812.     }
  813.  
  814.   else
  815.   {
  816.         GLuint i;
  817.         BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  818.         y=FLIP(y);
  819.         if (mask) {
  820.            for (i=0; i<n; i++)
  821.              if (mask[i])
  822.                Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));
  823.         }
  824.         else {
  825.            for (i=0; i<n; i++)
  826.              Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));
  827.             }
  828.     }
  829.    ENDPROFILE(write_color_span)
  830.  
  831. }
  832.  
  833. /*
  834.  * Write a horizontal span of pixels with a boolean mask.  The current color
  835.  * is used for all pixels.
  836.  */
  837. static void write_monocolor_span( GLcontext* ctx, 
  838.                                   GLuint n, GLint x, GLint y,
  839.                                   const GLubyte mask[])
  840. {
  841.   STARTPROFILE
  842.   GLuint i;
  843.   HDC DC=DD_GETDC;
  844.   PWMC    pwc = Current;
  845.  
  846.   assert(Current->rgb_flag==GL_TRUE);
  847.   y=FLIP(y);
  848.  
  849.   if(Current->rgb_flag==GL_TRUE){
  850.       for (i=0; i<n; i++)
  851.         if (mask[i])
  852. // Trying
  853.         wmSetPixel(pwc,y,x+i,GetRValue(Current->pixel), GetGValue(Current->pixel), GetBValue(Current->pixel));
  854.   }
  855.   else {
  856.       for (i=0; i<n; i++)
  857.         if (mask[i])
  858.             SetPixel(DC, y, x+i, Current->pixel);
  859.   }
  860.  
  861.     DD_RELEASEDC;
  862.  
  863.     ENDPROFILE(write_monocolor_span)
  864. }
  865.  
  866.  
  867.  
  868. /**********************************************************************/
  869. /*****                   Array-based pixel drawing                *****/
  870. /**********************************************************************/
  871.  
  872.  
  873. /* Write an array of pixels with a boolean mask. */
  874. static void write_index_pixels( GLcontext* ctx, 
  875.                                 GLuint n, const GLint x[], const GLint y[],
  876.                                 const GLuint index[], const GLubyte mask[] )
  877. {
  878.    STARTPROFILE
  879.    GLuint i;
  880.    assert(Current->rgb_flag==GL_FALSE);
  881.    for (i=0; i<n; i++) {
  882.       if (mask[i]) {
  883.          BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
  884.            *Mem = index[i];
  885.       }
  886.    }
  887.    ENDPROFILE(write_index_pixels)
  888. }
  889.  
  890.  
  891.  
  892. /*
  893.  * Write an array of pixels with a boolean mask.  The current color
  894.  * index is used for all pixels.
  895.  */
  896. static void write_monoindex_pixels( GLcontext* ctx, 
  897.                                     GLuint n,
  898.                                     const GLint x[], const GLint y[],
  899.                                     const GLubyte mask[] )
  900. {
  901.    STARTPROFILE
  902.    GLuint i;
  903.    assert(Current->rgb_flag==GL_FALSE);
  904.    for (i=0; i<n; i++) {
  905.       if (mask[i]) {
  906.          BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
  907.             *Mem = Current->pixel;
  908.       }
  909.    }
  910.    ENDPROFILE(write_monoindex_pixels)
  911. }
  912.  
  913.  
  914.  
  915. /* Write an array of pixels with a boolean mask. */
  916. static void write_color_pixels( GLcontext* ctx,
  917.                                 GLuint n, const GLint x[], const GLint y[],
  918.                                 const GLubyte r[], const GLubyte g[],
  919.                                 const GLubyte b[], const GLubyte a[],
  920.                                 const GLubyte mask[] )
  921. {
  922.     STARTPROFILE
  923.     GLuint i;
  924.     PWMC    pwc = Current;
  925.     HDC DC=DD_GETDC;
  926.     assert(Current->rgb_flag==GL_TRUE);
  927.     for (i=0; i<n; i++)
  928.         if (mask[i])
  929.             wmSetPixel(pwc, FLIP(y[i]),x[i],r[i],g[i],b[i]);
  930.     DD_RELEASEDC;
  931.     ENDPROFILE(write_color_pixels)
  932. }
  933.  
  934.  
  935.  
  936. /*
  937.  * Write an array of pixels with a boolean mask.  The current color
  938.  * is used for all pixels.
  939.  */
  940. static void write_monocolor_pixels( GLcontext* ctx,
  941.                                     GLuint n,
  942.                                     const GLint x[], const GLint y[],
  943.                                     const GLubyte mask[] )
  944. {
  945.     STARTPROFILE
  946.     GLuint i;
  947.     PWMC    pwc = Current;
  948.     HDC DC=DD_GETDC;
  949.     assert(Current->rgb_flag==GL_TRUE);
  950.     for (i=0; i<n; i++)
  951.         if (mask[i])
  952.             wmSetPixel(pwc, FLIP(y[i]),x[i],GetRValue(Current->pixel), 
  953.                         GetGValue(Current->pixel), GetBValue(Current->pixel));
  954.     DD_RELEASEDC;
  955.     ENDPROFILE(write_monocolor_pixels)
  956. }
  957.  
  958.  
  959.  
  960. /**********************************************************************/
  961. /*****            Read spans/arrays of pixels                     *****/
  962. /**********************************************************************/
  963.  
  964.  
  965. /* Read a horizontal span of color-index pixels. */
  966. static void read_index_span( GLcontext* ctx, GLuint n, GLint x, GLint y, GLuint index[])
  967. {
  968.   STARTPROFILE
  969.   GLuint i;
  970.   BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
  971.   assert(Current->rgb_flag==GL_FALSE);
  972.   for (i=0; i<n; i++)
  973.     index[i]=Mem[i];
  974.   ENDPROFILE(read_index_span)
  975.  
  976. }
  977.  
  978.  
  979.  
  980.  
  981. /* Read an array of color index pixels. */
  982. static void read_index_pixels( GLcontext* ctx, 
  983.                                GLuint n, const GLint x[], const GLint y[],
  984.                                GLuint indx[], const GLubyte mask[] )
  985. {
  986.    STARTPROFILE
  987.    GLuint i;
  988.   assert(Current->rgb_flag==GL_FALSE);
  989.   for (i=0; i<n; i++) {
  990.      if (mask[i]) {
  991.         indx[i]=*(Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]);
  992.      }
  993.   }
  994.    ENDPROFILE(read_index_pixels)
  995. }
  996.  
  997.  
  998.  
  999. /* Read a horizontal span of color pixels. */
  1000. static void read_color_span( GLcontext* ctx, 
  1001.                              GLuint n, GLint x, GLint y,
  1002.                              GLubyte red[], GLubyte green[],
  1003.                              GLubyte blue[], GLubyte alpha[] )
  1004. {
  1005.    STARTPROFILE
  1006.   UINT i;
  1007.   COLORREF Color;
  1008.   HDC DC=DD_GETDC;
  1009.   assert(Current->rgb_flag==GL_TRUE);
  1010.   y=FLIP(y);
  1011.   for (i=0; i<n; i++)
  1012.   {
  1013.     Color=GetPixel(DC,x+i,y);
  1014.     red[i]=GetRValue(Color);
  1015.     green[i]=GetGValue(Color);
  1016.     blue[i]=GetBValue(Color);
  1017.     alpha[i]=255;
  1018.   }
  1019.   DD_RELEASEDC;
  1020.   memset(alpha,0,n*sizeof(GLint));
  1021.    ENDPROFILE(read_color_span)
  1022. }
  1023.  
  1024.  
  1025. /* Read an array of color pixels. */
  1026. static void read_color_pixels( GLcontext* ctx,
  1027.                                GLuint n, const GLint x[], const GLint y[],
  1028.                                GLubyte red[], GLubyte green[],
  1029.                                GLubyte blue[], GLubyte alpha[],
  1030.                                const GLubyte mask[] )
  1031. {
  1032.    STARTPROFILE
  1033.   GLuint i;
  1034.   COLORREF Color;
  1035.   HDC DC=DD_GETDC;
  1036.   assert(Current->rgb_flag==GL_TRUE);
  1037.   for (i=0; i<n; i++) {
  1038.      if (mask[i]) {
  1039.         Color=GetPixel(DC,x[i],FLIP(y[i]));
  1040.         red[i]=GetRValue(Color);
  1041.         green[i]=GetGValue(Color);
  1042.         blue[i]=GetBValue(Color);
  1043.         alpha[i]=255;
  1044.      }
  1045.   }
  1046.   DD_RELEASEDC;
  1047.   memset(alpha,0,n*sizeof(GLint));
  1048.    ENDPROFILE(read_color_pixels)
  1049. }
  1050.  
  1051.  
  1052.  
  1053. /**********************************************************************/
  1054. /**********************************************************************/
  1055.  
  1056.  
  1057.  
  1058. void setup_DD_pointers( GLcontext* ctx )
  1059. {
  1060.    ctx->Driver.UpdateState = setup_DD_pointers;
  1061.    ctx->Driver.GetBufferSize = buffer_size;
  1062.    ctx->Driver.Finish = finish;
  1063.    ctx->Driver.Flush = flush;
  1064.  
  1065.    ctx->Driver.ClearIndex = clear_index;
  1066.    ctx->Driver.ClearColor = clear_color;
  1067.    ctx->Driver.Clear = clear;
  1068.  
  1069.    ctx->Driver.Index = set_index;
  1070.    ctx->Driver.Color = set_color;
  1071.    ctx->Driver.IndexMask = index_mask;
  1072.    ctx->Driver.ColorMask = color_mask;
  1073.  
  1074.    ctx->Driver.LogicOp = logicop;
  1075.    ctx->Driver.Dither = dither;
  1076.  
  1077.    ctx->Driver.SetBuffer = set_buffer;
  1078.    ctx->Driver.GetBufferSize = buffer_size;
  1079.  
  1080.    ctx->Driver.PointsFunc = choose_points_function(ctx);
  1081.    ctx->Driver.LineFunc = choose_line_function(ctx);
  1082.    ctx->Driver.TriangleFunc = choose_triangle_function( ctx );
  1083.    
  1084.    /* Pixel/span writing functions: */
  1085.    ctx->Driver.WriteColorSpan       = write_color_span;
  1086.    ctx->Driver.WriteMonocolorSpan   = write_monocolor_span;
  1087.    ctx->Driver.WriteColorPixels     = write_color_pixels;
  1088.    ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels;
  1089.    ctx->Driver.WriteIndexSpan       = write_index_span;
  1090.    ctx->Driver.WriteMonoindexSpan   = write_monoindex_span;
  1091.    ctx->Driver.WriteIndexPixels     = write_index_pixels;
  1092.    ctx->Driver.WriteMonoindexPixels = write_monoindex_pixels;
  1093.  
  1094.    /* Pixel/span reading functions: */
  1095.    ctx->Driver.ReadIndexSpan = read_index_span;
  1096.    ctx->Driver.ReadColorSpan = read_color_span;
  1097.    ctx->Driver.ReadIndexPixels = read_index_pixels;
  1098.    ctx->Driver.ReadColorPixels = read_color_pixels;
  1099. }
  1100.  
  1101.  
  1102. /**********************************************************************/
  1103. /*****                  WMesa API Functions                       *****/
  1104. /**********************************************************************/
  1105.  
  1106.  
  1107.  
  1108. #define PAL_SIZE 256
  1109. static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB)
  1110. {
  1111.    STARTPROFILE
  1112.     int i;
  1113.     HDC hdc;
  1114.     struct
  1115.     {
  1116.         WORD Version;
  1117.         WORD NumberOfEntries;
  1118.         PALETTEENTRY aEntries[PAL_SIZE];
  1119.     } Palette =
  1120.     {
  1121.         0x300,
  1122.         PAL_SIZE
  1123.     };
  1124.     hdc=GetDC(NULL);
  1125.     if (Pal!=NULL)
  1126.     GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries);
  1127.   else
  1128.     GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries);
  1129.     if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)
  1130.     {
  1131.         for(i = 0; i <PAL_SIZE; i++)
  1132.             Palette.aEntries[i].peFlags = PC_RESERVED;
  1133.         Palette.aEntries[255].peRed = 255;
  1134.         Palette.aEntries[255].peGreen = 255;
  1135.         Palette.aEntries[255].peBlue = 255;
  1136.         Palette.aEntries[255].peFlags = 0;
  1137.         Palette.aEntries[0].peRed = 0;
  1138.         Palette.aEntries[0].peGreen = 0;
  1139.         Palette.aEntries[0].peBlue = 0;
  1140.         Palette.aEntries[0].peFlags = 0;
  1141.     }
  1142.     else
  1143.     {
  1144.         int nStaticColors;
  1145.         int nUsableColors;
  1146.         nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2;
  1147.         for (i=0; i<nStaticColors; i++)
  1148.             Palette.aEntries[i].peFlags = 0;
  1149.         nUsableColors = PAL_SIZE-nStaticColors;
  1150.         for (; i<nUsableColors; i++)
  1151.             Palette.aEntries[i].peFlags = PC_RESERVED;
  1152.         for (; i<PAL_SIZE-nStaticColors; i++)
  1153.             Palette.aEntries[i].peFlags = PC_RESERVED;
  1154.         for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++)
  1155.             Palette.aEntries[i].peFlags = 0;
  1156.     }
  1157.     ReleaseDC(NULL,hdc);
  1158.   for (i=0; i<PAL_SIZE; i++)
  1159.   {
  1160.     aRGB[i].rgbRed=Palette.aEntries[i].peRed;
  1161.     aRGB[i].rgbGreen=Palette.aEntries[i].peGreen;
  1162.     aRGB[i].rgbBlue=Palette.aEntries[i].peBlue;
  1163.     aRGB[i].rgbReserved=Palette.aEntries[i].peFlags;
  1164.   }
  1165.         ENDPROFILE(GetPalette)
  1166. }
  1167.  
  1168.  
  1169. WMesaContext WMesaCreateContext( HWND hWnd, HPALETTE* Pal, 
  1170.                                               GLboolean rgb_flag,
  1171.                                               GLboolean db_flag )
  1172. {
  1173.   RECT CR;
  1174.   WMesaContext c;
  1175.   GLboolean true_color_flag; 
  1176.   c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context));
  1177.   if (!c)
  1178.     return NULL;
  1179.       
  1180.   c->Window=hWnd;
  1181.   c->hDC = GetDC(hWnd);
  1182.   true_color_flag = GetDeviceCaps(c->hDC, BITSPIXEL) > 8;
  1183. #ifdef DDRAW
  1184.   if(true_color_flag) c->rgb_flag = rgb_flag = GL_TRUE; 
  1185. #endif
  1186.  
  1187.  
  1188. #ifdef DITHER
  1189.   if ((true_color_flag==GL_FALSE) && (rgb_flag == GL_TRUE)){
  1190.     c->dither_flag = GL_TRUE;
  1191.     c->hPalHalfTone = WinGCreateHalftonePalette();
  1192.   }
  1193.   else
  1194.     c->dither_flag = GL_FALSE;
  1195. #else
  1196.     c->dither_flag = GL_FALSE;
  1197. #endif
  1198.  
  1199.   
  1200.   if (rgb_flag==GL_FALSE)
  1201.   {
  1202.     c->rgb_flag = GL_FALSE;
  1203. //    c->pixel = 1;
  1204.     c->db_flag = db_flag =GL_TRUE; // WinG requires double buffering
  1205.     printf("Single buffer is not supported in color index mode, setting to double buffer.\n");   
  1206.   }
  1207.   else
  1208.   {
  1209.     c->rgb_flag = GL_TRUE;
  1210. //    c->pixel = 0;
  1211.   }
  1212.   GetClientRect(c->Window,&CR);
  1213.   c->width=CR.right;
  1214.   c->height=CR.bottom;
  1215.   if (db_flag)
  1216.   {
  1217.     c->db_flag = 1;
  1218.     /* Double buffered */
  1219. #ifndef DDRAW
  1220. //    if (c->rgb_flag==GL_TRUE && c->dither_flag != GL_TRUE )
  1221.     {
  1222.         wmCreateBackingStore(c, c->width, c->height);
  1223.  
  1224.     }
  1225. #endif
  1226.   }
  1227.   else
  1228.   {
  1229.     /* Single Buffered */
  1230.     if (c->rgb_flag)
  1231.       c->db_flag = 0;
  1232.   }
  1233. #ifdef DDRAW  
  1234.   if (DDInit(c,hWnd) == GL_FALSE) {
  1235.         free( (void *) c );    
  1236.         exit(1);
  1237.         }
  1238. #endif    
  1239.  
  1240.   
  1241.   c->gl_visual = gl_create_visual(rgb_flag,
  1242.                                   GL_FALSE,    /* software alpha */
  1243.                                   db_flag,    /* db_flag */
  1244.                                   16,        /* depth_bits */
  1245.                                   8,        /* stencil_bits */
  1246.                                   8,        /* accum_bits */
  1247.                                   8,
  1248.                                   255.0, 255.0, 255.0, 255.0, 
  1249.                                   8,8,8,8 );    
  1250.   
  1251.     if (!c->gl_visual) {
  1252.          return NULL;
  1253.       }
  1254.  
  1255.   /* allocate a new Mesa context */
  1256.   c->gl_ctx = gl_create_context( c->gl_visual, NULL,c);
  1257.  
  1258.   if (!c->gl_ctx) {
  1259.          gl_destroy_visual( c->gl_visual );
  1260.          free(c);
  1261.          return NULL;
  1262.       }
  1263.  
  1264.       c->gl_buffer = gl_create_framebuffer( c->gl_visual );
  1265.       if (!c->gl_buffer) {
  1266.          gl_destroy_visual( c->gl_visual );
  1267.          gl_destroy_context( c->gl_ctx );
  1268.          free(c);
  1269.          return NULL;
  1270.       }
  1271. //  setup_DD_pointers(c->gl_ctx);
  1272.  
  1273.   return c;
  1274. }
  1275.  
  1276. void WMesaDestroyContext( void )
  1277. {
  1278.     WMesaContext c = Current;
  1279.     ReleaseDC(c->Window,c->hDC);
  1280.     WC = c;
  1281.     if(c->hPalHalfTone != NULL)    
  1282.         DeleteObject(c->hPalHalfTone);
  1283.     gl_destroy_visual( c->gl_visual );
  1284.     gl_destroy_framebuffer( c->gl_buffer );
  1285.     gl_destroy_context( c->gl_ctx );
  1286.  
  1287.     if (c->db_flag)
  1288. #ifdef DDRAW
  1289.         DDFree(c);
  1290. #else
  1291.         wmDeleteBackingStore(c);
  1292. #endif        
  1293.     free( (void *) c );
  1294. //Following code is added to enable parallel render
  1295. // Parallel render only work in double buffer mode
  1296. #if !defined(NO_PARALLEL)
  1297.     if(parallelMachine)
  1298.         PRDestroyRenderBuffer();
  1299. #endif
  1300. // End modification
  1301. }
  1302.  
  1303.  
  1304.  
  1305. void /*APIENTRY*/ WMesaMakeCurrent( WMesaContext c )
  1306. {
  1307.     if(!c){
  1308.         Current = c;
  1309.         return;
  1310.     }
  1311.     
  1312.     //
  1313.     // A little optimization
  1314.     // If it already is current,
  1315.     // don't set it again
  1316.     //
  1317.     if(Current == c)
  1318.         return;
  1319.  
  1320.     //gl_set_context( c->gl_ctx );
  1321.     gl_make_current(c->gl_ctx, c->gl_buffer);
  1322.     Current = c;
  1323.     setup_DD_pointers(c->gl_ctx);
  1324.     if (Current->gl_ctx->Viewport.Width==0) {
  1325.       /* initialize viewport to window size */
  1326.       gl_Viewport( Current->gl_ctx,
  1327.                    0, 0, Current->width, Current->height );
  1328.     }
  1329.     if ((c->cColorBits <= 8 ) && (c->rgb_flag == GL_TRUE)){
  1330.             WMesaPaletteChange(c->hPalHalfTone);
  1331.     }
  1332. }
  1333.  
  1334.  
  1335.  
  1336. void /*APIENTRY*/ WMesaSwapBuffers( void )
  1337. {
  1338.   HDC DC = Current->hDC;
  1339.   if (Current->db_flag)
  1340.     wmFlush(Current);
  1341. }
  1342.  
  1343.  
  1344.  
  1345. void /*APIENTRY*/ WMesaPaletteChange(HPALETTE Pal)
  1346. {
  1347.   int vRet;
  1348.   LPPALETTEENTRY pPal;
  1349.   if (Current && (Current->rgb_flag==GL_FALSE || Current->dither_flag == GL_TRUE))
  1350.   {
  1351.     pPal = (PALETTEENTRY *)malloc( 256 * sizeof(PALETTEENTRY));
  1352.     Current->hPal=Pal;
  1353. //    GetPaletteEntries( Pal, 0, 256, pPal );
  1354.     GetPalette( Pal, pPal );
  1355. #ifdef DDRAW
  1356.     Current->lpDD->lpVtbl->CreatePalette(Current->lpDD,DDPCAPS_8BIT, 
  1357.         pPal, &(Current->lpDDPal), NULL);
  1358.     if (Current->lpDDPal)
  1359.         Current->lpDDSPrimary->lpVtbl->SetPalette(Current->lpDDSPrimary,Current->lpDDPal);
  1360. #else
  1361.     vRet = SetDIBColorTable(Current->dib.hDC,0,256,pPal);
  1362. #endif
  1363.     free( pPal );
  1364.   }
  1365.   
  1366. }
  1367.  
  1368.  
  1369.  
  1370.  
  1371. static unsigned char threeto8[8] = {
  1372.     0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
  1373. };
  1374.  
  1375. static unsigned char twoto8[4] = {
  1376.     0, 0x55, 0xaa, 0xff
  1377. };
  1378.  
  1379. static unsigned char oneto8[2] = {
  1380.     0, 255
  1381. };
  1382.  
  1383. static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift)
  1384. {
  1385.     unsigned char val;
  1386.  
  1387.     val = i >> shift;
  1388.     switch (nbits) {
  1389.  
  1390.         case 1:
  1391.             val &= 0x1;
  1392.             return oneto8[val];
  1393.  
  1394.         case 2:
  1395.             val &= 0x3;
  1396.             return twoto8[val];
  1397.  
  1398.         case 3:
  1399.             val &= 0x7;
  1400.             return threeto8[val];
  1401.  
  1402.         default:
  1403.             return 0;
  1404.     }
  1405. }
  1406.  
  1407. void /*WINAPI*/ wmCreatePalette( PWMC pwdc )
  1408. {
  1409.     /* Create a compressed and re-expanded 3:3:2 palette */
  1410.       int            i;
  1411.     LOGPALETTE     *pPal;
  1412.     BYTE           rb, rs, gb, gs, bb, bs;
  1413.  
  1414.     pwdc->nColors = 0x100;
  1415.  
  1416.     pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY));
  1417.     memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) );
  1418.  
  1419.     pPal->palVersion = 0x300;
  1420.  
  1421.     rb = REDBITS;
  1422.     rs = REDSHIFT;
  1423.     gb = GREENBITS;
  1424.     gs = GREENSHIFT;
  1425.     bb = BLUEBITS;
  1426.     bs = BLUESHIFT;
  1427.  
  1428.     if (pwdc->db_flag) {
  1429.  
  1430.         /* Need to make two palettes: one for the screen DC and one for the DIB. */
  1431.         pPal->palNumEntries = pwdc->nColors;
  1432.         for (i = 0; i < pwdc->nColors; i++) {
  1433.             pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
  1434.             pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
  1435.             pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
  1436.             pPal->palPalEntry[i].peFlags = 0;
  1437.         }
  1438.         pwdc->hGLPalette = CreatePalette( pPal );
  1439.         pwdc->hPalette = CreatePalette( pPal );
  1440.     } 
  1441.  
  1442.     else {
  1443.         pPal->palNumEntries = pwdc->nColors;
  1444.         for (i = 0; i < pwdc->nColors; i++) {
  1445.             pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
  1446.             pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
  1447.             pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
  1448.             pPal->palPalEntry[i].peFlags = 0;
  1449.         }
  1450.         pwdc->hGLPalette = CreatePalette( pPal );
  1451.     }
  1452.     
  1453.     free(pPal);
  1454.  
  1455. }
  1456.  
  1457. void /*WINAPI*/ wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
  1458. {
  1459.     if(Current->db_flag){
  1460.         LPBYTE    lpb = pwc->pbPixels;
  1461.         LPDWORD    lpdw;
  1462.         LPWORD    lpw;
  1463.         UINT    nBypp = pwc->cColorBits / 8;
  1464.         UINT    nOffset = iPixel % nBypp;
  1465.  
  1466.         // Move the pixel buffer pointer to the scanline that we
  1467.         // want to access
  1468.  
  1469. //        pwc->dib.fFlushed = FALSE;
  1470.  
  1471.         lpb += pwc->ScanWidth * iScanLine;
  1472.         // Now move to the desired pixel
  1473.         lpb += iPixel * nBypp;
  1474.         lpb = PIXELADDR(iPixel, iScanLine);
  1475.         lpdw = (LPDWORD)lpb;
  1476.         lpw = (LPWORD)lpb;
  1477.  
  1478.         if(nBypp == 1){
  1479.             if(pwc->dither_flag)
  1480.                 *lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel);
  1481.             else
  1482.                 *lpb = BGR8(r,g,b);
  1483.         }
  1484.         else if(nBypp == 2)
  1485.             *lpw = BGR16(r,g,b);
  1486.         else if (nBypp == 3){
  1487.             *lpdw = BGR24(r,g,b);
  1488.         }
  1489.         else if (nBypp == 4)
  1490.             *lpdw = BGR32(r,g,b);
  1491.     }
  1492.     else{
  1493.         HDC DC = DD_GETDC;
  1494.         SetPixel(DC, iPixel, iScanLine, RGB(r,g,b));
  1495.         DD_RELEASEDC;
  1496.     }
  1497. }
  1498.  
  1499. void /*WINAPI*/ wmCreateDIBSection(
  1500.     HDC     hDC,
  1501.     PWMC pwc,    // handle of device context
  1502.     CONST BITMAPINFO *pbmi,    // address of structure containing bitmap size, format, and color data
  1503.     UINT iUsage    // color data type indicator: RGB values or palette indices
  1504. )
  1505. {
  1506.     DWORD    dwSize = 0;
  1507.     DWORD    dwScanWidth;
  1508.     UINT    nBypp = pwc->cColorBits / 8;
  1509.     HDC        hic;
  1510.     
  1511.     dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3);
  1512.  
  1513.     pwc->ScanWidth =pwc->pitch = dwScanWidth;
  1514.  
  1515.     if (stereo_flag)
  1516.         pwc->ScanWidth = 2* pwc->pitch;
  1517.  
  1518.     dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height);
  1519.  
  1520.     pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE,
  1521.                                           NULL,
  1522.                                           PAGE_READWRITE | SEC_COMMIT,
  1523.                                           0,
  1524.                                           dwSize,
  1525.                                           NULL);
  1526.  
  1527.     if (!pwc->dib.hFileMap)
  1528.         return;
  1529.  
  1530.     pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap,
  1531.                                   FILE_MAP_ALL_ACCESS,
  1532.                                   0,
  1533.                                   0,
  1534.                                   0);
  1535.  
  1536.     if(!pwc->dib.base){
  1537.         CloseHandle(pwc->dib.hFileMap);
  1538.         return;
  1539.     }
  1540.  
  1541. //    pwc->pbPixels = pwc->addrOffScreen = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);
  1542.  
  1543. //    pwc->dib.hDC = CreateCompatibleDC(hDC);
  1544.  
  1545.     CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO));
  1546.  
  1547.     hic = CreateIC("display", NULL, NULL, NULL);
  1548.     pwc->dib.hDC = CreateCompatibleDC(hic);
  1549.  
  1550.  
  1551. /*    pwc->hbmDIB = CreateDIBitmap(hic,
  1552.                          &(pwc->bmi.bmiHeader),
  1553.                          CBM_INIT,
  1554.                          pwc->pbPixels,
  1555.                          &(pwc->bmi),
  1556.                          DIB_RGB_COLORS);
  1557. */
  1558.   pwc->hbmDIB = CreateDIBSection(hic,
  1559.                         &(pwc->bmi),
  1560.                         (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS),
  1561.                         &(pwc->pbPixels),
  1562.                         pwc->dib.hFileMap,
  1563.                         0);
  1564.   /*
  1565.     pwc->hbmDIB = CreateDIBSection(hic,
  1566.                         &(pwc->bmi),
  1567.                         DIB_RGB_COLORS,
  1568.                         &(pwc->pbPixels),
  1569.                         pwc->dib.hFileMap,
  1570.                         0);
  1571.     */
  1572.     pwc->ScreenMem = pwc->addrOffScreen = pwc->pbPixels;
  1573.     pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);
  1574.  
  1575.     DeleteDC(hic);
  1576.  
  1577.     return;
  1578.  
  1579. }
  1580.  
  1581. //
  1582. // Blit memory DC to screen DC
  1583. //
  1584. BOOL /*WINAPI*/ wmFlush(PWMC pwc)
  1585. {
  1586.     BOOL    bRet = 0;
  1587.     DWORD    dwErr = 0;
  1588.     HRESULT             ddrval;
  1589.  
  1590.     // Now search through the torus frames and mark used colors
  1591.     if(pwc->db_flag){
  1592. #ifdef DDRAW
  1593.         if (pwc->lpDDSOffScreen == NULL)
  1594.         if(DDCreateOffScreen(pwc) == GL_FALSE)
  1595.             return;
  1596.         
  1597.         pwc->lpDDSOffScreen->lpVtbl->Unlock(pwc->lpDDSOffScreen, NULL);
  1598.  
  1599.         while( 1 )
  1600.         {
  1601.             ddrval = pwc->lpDDSPrimary->lpVtbl->Blt( pwc->lpDDSPrimary,
  1602.                     &(pwc->rectSurface), pwc->lpDDSOffScreen, &(pwc->rectOffScreen), 0, NULL );
  1603.  
  1604.             if( ddrval == DD_OK )
  1605.             {
  1606.                 break;
  1607.             }
  1608.             if( ddrval == DDERR_SURFACELOST )
  1609.             {
  1610.                 if(!DDRestoreAll(pwc))
  1611.                 {
  1612.                     break;
  1613.                 }
  1614.             }
  1615.             if( ddrval != DDERR_WASSTILLDRAWING )
  1616.             {
  1617.                 break;
  1618.             }
  1619.         }
  1620.  
  1621.         while (pwc->lpDDSOffScreen->lpVtbl->Lock(pwc->lpDDSOffScreen,
  1622.                         NULL, &(pwc->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING)
  1623.             ;
  1624.         
  1625.         if(ddrval != DD_OK)
  1626.             dwErr = GetLastError();
  1627. #else
  1628.     bRet = BitBlt(pwc->hDC, 0, 0, pwc->width, pwc->height, 
  1629.            pwc->dib.hDC, 0, 0, SRCCOPY);
  1630. #endif
  1631.     }
  1632.  
  1633.     return(TRUE);
  1634.  
  1635. }
  1636.  
  1637.  
  1638. // The following code is added by Li Wei to enable stereo display
  1639.  
  1640. #if !defined(NO_STEREO)
  1641.  
  1642. void WMesaShowStereo(GLuint list)
  1643. {
  1644.  
  1645.     GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
  1646.     GLfloat cm[16];
  1647.     GLint matrix_mode;
  1648.     // Must use double Buffer 
  1649.     if( ! Current-> db_flag )
  1650.         return;
  1651.  
  1652.     
  1653.     glGetIntegerv(GL_MATRIX_MODE,&matrix_mode);
  1654.  
  1655. //    glPushMatrix();  //****
  1656.     WMesaViewport(Current->gl_ctx,0,Current->height/2,Current->width,Current->height/2);
  1657. //    Current->gl_ctx->NewState = 0;
  1658.  
  1659.     //    glViewport(0,0,Current->width,Current->height/2);
  1660.     if(matrix_mode!=GL_MODELVIEW)
  1661.         glMatrixMode(GL_MODELVIEW);
  1662.     
  1663.     glGetFloatv(GL_MODELVIEW_MATRIX,cm);
  1664.     glLoadIdentity();
  1665.     gluLookAt(viewDistance/2,0.0,0.0 ,
  1666.              viewDistance/2,0.0,-1.0,
  1667.              0.0,1.0,0.0 );
  1668. //    glTranslatef(viewDistance/2.0,0.,0.);
  1669.     glMultMatrixf( cm );
  1670.  
  1671.     Current->ScreenMem = Current->pbPixels = Current->addrOffScreen;
  1672.     //glPushMatrix();
  1673.     glCallList( list );
  1674.     //glPopMatrix();
  1675.  
  1676.     glGetFloatv(GL_MODELVIEW_MATRIX,cm);
  1677.     glLoadIdentity();
  1678.     gluLookAt(-viewDistance/2,0.0,0.0 ,
  1679.              -viewDistance/2,0.0,-1.0,
  1680.              0.0,1.0,0.0 );
  1681. //    glTranslatef(-viewDistance/2.0,0.,0.);
  1682.     glMultMatrixf(cm);
  1683.     
  1684.     Current->ScreenMem = Current->pbPixels = Current->addrOffScreen + Current->pitch;
  1685.     glCallList(list);
  1686.     if(matrix_mode!=GL_MODELVIEW)
  1687.         glMatrixMode(matrix_mode);
  1688.  
  1689. //    glPopMatrix();
  1690.     glFlush();
  1691.  
  1692.     WMesaViewport(Current->gl_ctx,0,0,Current->width,Current->height);
  1693. //    Current->gl_ctx->NewState = 0;
  1694.     WMesaSwapBuffers();
  1695.  
  1696. }
  1697.  
  1698. void toggleStereoMode()
  1699. {
  1700.     if(!Current->db_flag)
  1701.         return;
  1702.     if(!stereo_flag){
  1703.         stereo_flag = 1;
  1704.         if(stereoBuffer==GL_FALSE)
  1705. #if !defined(NO_PARALLEL)
  1706.             if(!parallelFlag)
  1707. #endif
  1708.         {
  1709.             Current->ScanWidth = Current->pitch*2;
  1710.             }
  1711.     }
  1712.     else {
  1713.         stereo_flag = 0;
  1714. #if !defined(NO_PARALLEL)
  1715.         if(!parallelFlag)
  1716. #endif
  1717.         Current->ScanWidth = Current->pitch;
  1718.         Current->pbPixels = Current->addrOffScreen;
  1719.     }
  1720. }
  1721.  
  1722. /* if in stereo mode, the following function is called */
  1723. void glShowStereo(GLuint list)
  1724. {
  1725.     WMesaShowStereo(list);
  1726. }
  1727.  
  1728. #endif // End if NO_STEREO not defined
  1729.  
  1730. #if !defined(NO_PARALLEL)
  1731.  
  1732. void toggleParallelMode(void)
  1733. {
  1734.     if(!parallelFlag){
  1735.         parallelFlag = GL_TRUE;
  1736.         if(parallelMachine==GL_FALSE){
  1737.                 PRCreateRenderBuffer( Current->rgb_flag? GL_RGBA :GL_COLOR_INDEX,
  1738.                                       Current->cColorBits/8,
  1739.                                       Current->width ,Current->height, 
  1740.                                       Current->ScanWidth,
  1741.                                       Current->rgb_flag? Current->pbPixels: Current->ScreenMem);
  1742.                 parallelMachine = GL_TRUE;
  1743.                 }
  1744.         }
  1745.     else {
  1746.         parallelFlag = GL_FALSE;
  1747.         if(parallelMachine==GL_TRUE){
  1748.                 PRDestroyRenderBuffer();
  1749.                 parallelMachine=GL_FALSE;
  1750.                 ReadyForNextFrame = GL_TRUE;
  1751.                 }
  1752.  
  1753. /***********************************************
  1754. // Seems something wrong!!!! 
  1755. ************************************************/
  1756.  
  1757.         WMesaMakeCurrent(Current);
  1758. #if !defined(NO_STEREO)
  1759.         stereo_flag = GL_FALSE ;
  1760. #endif
  1761.     }
  1762. }
  1763.  
  1764. void PRShowRenderResult(void)
  1765. {
  1766.     int flag = 0;
  1767. if(!glImageRendered())
  1768.         return;
  1769.  
  1770.   if (parallelFlag)
  1771.     {
  1772.       WMesaSwapBuffers();
  1773.      }
  1774.  
  1775. }
  1776. #endif //End if NO_PARALLEL not defined
  1777.  
  1778. //end modification
  1779.  
  1780. BYTE DITHER_RGB_2_8BIT( int red, int green, int blue, int pixel, int scanline)
  1781. {
  1782.     char unsigned redtemp, greentemp, bluetemp, paletteindex;
  1783.  
  1784.     //*** now, look up each value in the halftone matrix
  1785.     //*** using an 8x8 ordered dither.
  1786.     redtemp = aDividedBy51[red]
  1787.           + (aModulo51[red] > aHalftone8x8[(pixel%8)*8
  1788.           + scanline%8]);
  1789.     greentemp = aDividedBy51[(char unsigned)green]
  1790.           + (aModulo51[green] > aHalftone8x8[
  1791.           (pixel%8)*8 + scanline%8]);
  1792.     bluetemp = aDividedBy51[(char unsigned)blue]
  1793.           + (aModulo51[blue] > aHalftone8x8[
  1794.           (pixel%8)*8 +scanline%8]);
  1795.  
  1796.     //*** recombine the halftoned rgb values into a palette index
  1797.     paletteindex =
  1798.     redtemp + aTimes6[greentemp] + aTimes36[bluetemp];
  1799.  
  1800.     //*** and translate through the wing halftone palette
  1801.     //*** translation vector to give the correct value.
  1802.     return aWinGHalftoneTranslation[paletteindex];
  1803. }
  1804.  
  1805. #ifdef DDRAW
  1806. /*
  1807.  * restoreAll
  1808.  *
  1809.  * restore all lost objects
  1810.  */
  1811. HRESULT DDRestoreAll( WMesaContext wc )
  1812. {
  1813.     HRESULT     ddrval;
  1814.  
  1815.     ddrval = wc->lpDDSPrimary->lpVtbl->Restore(wc->lpDDSPrimary);
  1816.     if( ddrval == DD_OK )
  1817.     {
  1818.         ddrval = wc->lpDDSOffScreen->lpVtbl->Restore(wc->lpDDSOffScreen);
  1819.     }
  1820.     return ddrval;
  1821.  
  1822. } /* restoreAll */
  1823.  
  1824.  
  1825. /*
  1826.  * This function is called if the initialization function fails
  1827.  */
  1828. BOOL initFail( HWND hwnd, WMesaContext wc )
  1829. {
  1830.     DDFree(wc);
  1831.     MessageBox( hwnd, "DirectDraw Init FAILED", "", MB_OK );
  1832.     return FALSE;
  1833.  
  1834. } /* initFail */
  1835.  
  1836.  
  1837. static void DDDeleteOffScreen(WMesaContext wc)
  1838. {
  1839.         if( wc->lpDDSOffScreen != NULL )
  1840.         {
  1841.             wc->lpDDSOffScreen->lpVtbl->Unlock(wc->lpDDSOffScreen,NULL);
  1842.             wc->lpDDSOffScreen->lpVtbl->Release(wc->lpDDSOffScreen);
  1843.             wc->lpDDSOffScreen = NULL;
  1844.         }
  1845.  
  1846. }
  1847.  
  1848. static void DDFreePrimarySurface(WMesaContext wc)
  1849. {
  1850.         if( wc->lpDDSPrimary != NULL )
  1851.         {
  1852.             if(wc->db_flag == GL_FALSE)
  1853.                 wc->lpDDSPrimary->lpVtbl->ReleaseDC(wc->lpDDSPrimary, wc->hDC);
  1854.             wc->lpDDSPrimary->lpVtbl->Release(wc->lpDDSPrimary);
  1855.             wc->lpDDSPrimary = NULL;
  1856.         }
  1857. }
  1858.  
  1859. static BOOL DDCreatePrimarySurface(WMesaContext wc)
  1860. {
  1861.     HRESULT ddrval;
  1862.     DDSCAPS             ddscaps;
  1863.     wc->ddsd.dwSize = sizeof( wc->ddsd );
  1864.     wc->ddsd.dwFlags = DDSD_CAPS;
  1865.     wc->ddsd.ddsCaps.dwCaps =    DDSCAPS_PRIMARYSURFACE;
  1866.  
  1867.     ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD,&(wc->ddsd), &(wc->lpDDSPrimary), NULL );
  1868.     if( ddrval != DD_OK )
  1869.     {
  1870.         return initFail(wc->hwnd , wc);
  1871.     }
  1872.     if(wc->db_flag == GL_FALSE)
  1873.          wc->lpDDSPrimary->lpVtbl->GetDC(wc->lpDDSPrimary, wc->hDC);
  1874.     return TRUE;
  1875. }
  1876.  
  1877. static BOOL DDCreateOffScreen(WMesaContext wc)
  1878. {
  1879.     POINT    pt;
  1880.     HRESULT        ddrval;
  1881.     if(wc->lpDD == NULL)
  1882.         return FALSE;
  1883.     GetClientRect( wc->hwnd, &(wc->rectOffScreen) );
  1884.     wc->ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
  1885.     wc->ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  1886.     wc->ddsd.dwHeight = wc->rectOffScreen.bottom - wc->rectOffScreen.top;
  1887.     wc->ddsd.dwWidth = wc->rectOffScreen.right - wc->rectOffScreen.left;
  1888.  
  1889.     ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD, &(wc->ddsd), &(wc->lpDDSOffScreen), NULL );
  1890.     if( ddrval != DD_OK )
  1891.     {
  1892.         return FALSE;
  1893.     }
  1894.     
  1895.     while (wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING)
  1896.         ;
  1897. //    while ((ddrval = wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), DDLOCK_SURFACEMEMORYPTR , NULL)) != DD_OK)
  1898.         ;
  1899.     if(wc->ddsd.lpSurface==NULL)
  1900.         return initFail(wc->hwnd, wc);
  1901.             
  1902.     wc->ScreenMem = wc->pbPixels = wc->addrOffScreen = (PBYTE)(wc->ddsd.lpSurface);
  1903.     wc->ScanWidth = wc->pitch = wc->ddsd.lPitch;
  1904.     if (stereo_flag)
  1905.         wc->ScanWidth = wc->ddsd.lPitch*2;
  1906.  
  1907.     GetClientRect( wc->hwnd, &(wc->rectSurface) );
  1908.     pt.x = pt.y = 0;
  1909.     ClientToScreen( wc->hwnd, &pt );
  1910.     OffsetRect(&(wc->rectSurface), pt.x, pt.y);
  1911.     wmSetPixelFormat(wc, wc->hDC);
  1912.     return TRUE;
  1913. }
  1914.  
  1915. /*
  1916.  * doInit - do work required for every instance of the application:
  1917.  *                create the window, initialize data
  1918.  */
  1919. static BOOL DDInit( WMesaContext wc, HWND hwnd)
  1920. {
  1921.     HRESULT             ddrval;
  1922.     DWORD dwFrequency;
  1923.  
  1924.     LPDIRECTDRAW            lpDD;           // DirectDraw object
  1925.     LPDIRECTDRAW2            lpDD2;   
  1926.  
  1927.  
  1928.     wc->fullScreen = displayOptions.fullScreen;
  1929.     wc->gMode = displayOptions.mode;
  1930.     wc->hwnd = hwnd;
  1931.     stereo_flag = displayOptions.stereo;
  1932.     if(wc->db_flag!= GL_TRUE)
  1933.         stereo_flag = GL_FALSE;
  1934.     /*
  1935.      * create the main DirectDraw object
  1936.      */
  1937.     ddrval = DirectDrawCreate( NULL, &(wc->lpDD), NULL );
  1938.     if( ddrval != DD_OK )
  1939.     {
  1940.         return initFail(hwnd,wc);
  1941.     }
  1942.  
  1943.     // Get exclusive mode if requested
  1944.     if(wc->fullScreen)
  1945.     {
  1946.         ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
  1947.     }
  1948.     else
  1949.     {
  1950.         ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd, DDSCL_NORMAL );
  1951.     }
  1952.     if( ddrval != DD_OK )
  1953.     {
  1954.         return initFail(hwnd , wc);
  1955.     }
  1956.  
  1957.  
  1958. /*    ddrval = wc->lpDD->lpVtbl->QueryInterface(wc->lpDD, IID_IDirectDraw2, 
  1959.             (LPVOID *)((wc->lpDD2)));
  1960.  
  1961. */
  1962.     if(ddrval != DD_OK)
  1963.         return initFail(hwnd , wc);
  1964.  
  1965.  
  1966.    //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd)); 
  1967.  //  wc->lpDD2->lpVtbl->GetMonitorFrequency(wc->lpDD, &dwFrequency);
  1968.     switch( wc->gMode )
  1969.     {
  1970.         case 1:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 640, 480, displayOptions.bpp); break;
  1971.         case 2:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 800, 600, displayOptions.bpp); break;
  1972.         case 3:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1024, 768, displayOptions.bpp); break;
  1973.         case 4:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1152, 864, displayOptions.bpp); break;
  1974.         case 5:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1280, 1024, displayOptions.bpp); break;
  1975.     }
  1976.  
  1977.     if( ddrval != DD_OK )
  1978.     {
  1979.         printf("Can't modify display mode, current mode used\n");
  1980. //        return initFail(hwnd , wc);
  1981.     }
  1982. //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd)); 
  1983. switch(ddrval){
  1984. case DDERR_INVALIDOBJECT:
  1985.     break;
  1986. case DDERR_INVALIDPARAMS:
  1987.     break;
  1988. case DDERR_UNSUPPORTEDMODE:
  1989.     ;
  1990. }
  1991.  
  1992.     if(DDCreatePrimarySurface(wc) == GL_FALSE)
  1993.         return initFail(hwnd, wc);
  1994.  
  1995.     if(wc->db_flag)
  1996.         return DDCreateOffScreen(wc);
  1997. } /* DDInit */
  1998.  
  1999. static void DDFree( WMesaContext wc)
  2000. {
  2001.     if( wc->lpDD != NULL )
  2002.     {
  2003.         DDFreePrimarySurface(wc);
  2004.         DDDeleteOffScreen(wc);
  2005.         wc->lpDD->lpVtbl->Release(wc->lpDD);
  2006.         wc->lpDD = NULL;
  2007.     }
  2008.     // Clean up the screen on exit
  2009.     RedrawWindow( NULL, NULL, NULL, RDW_INVALIDATE | RDW_ERASE |
  2010.                      RDW_ALLCHILDREN );
  2011.  
  2012. }
  2013. #endif
  2014.  
  2015. void WMesaMove(void)
  2016. {
  2017.     WMesaContext wc = Current;
  2018.     POINT    pt;
  2019.     if (Current != NULL){
  2020.         GetClientRect( wc->hwnd, &(wc->rectSurface) );
  2021.         pt.x = pt.y = 0;
  2022.         ClientToScreen( wc->hwnd, &pt );
  2023.         OffsetRect(&(wc->rectSurface), pt.x, pt.y);    
  2024.     }
  2025. }
  2026.  
  2027. /*
  2028.  * Like PACK_8A8B8G8R() but don't use alpha.  This is usually an acceptable
  2029.  * shortcut.
  2030.  */
  2031. #define PACK_8B8G8R( R, G, B )   ( ((B) << 16) | ((G) << 8) | (R) )
  2032.  
  2033.  
  2034. /**********************************************************************/
  2035. /***                   Triangle rendering                            ***/
  2036. /**********************************************************************/
  2037.  
  2038.  
  2039.  
  2040. /*
  2041.  * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
  2042.  */
  2043. static void smooth_8A8B8G8R_z_triangle( GLcontext *ctx,
  2044.                                          GLuint v0, GLuint v1, GLuint v2,
  2045.                                          GLuint pv )
  2046. {
  2047. WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2048. #define INTERP_Z 1
  2049. #define INTERP_RGB 1
  2050. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  2051. #define PIXEL_TYPE GLuint
  2052. //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2053. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2054. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  2055. {                                    \
  2056.    GLint i, len = RIGHT-LEFT;                        \
  2057.    for (i=0;i<len;i++) {                        \
  2058.       GLdepth z = FixedToDepth(ffz);                    \
  2059.       if (z < zRow[i]) {                        \
  2060.          pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg),    \
  2061.                  FixedToInt(ffb) );            \
  2062.          zRow[i] = z;                            \
  2063.       }                                    \
  2064.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  2065.       ffz += fdzdx;                            \
  2066.    }                                    \
  2067. }
  2068. #include "tritemp.h"
  2069. }
  2070.  
  2071.  
  2072. /*
  2073.  * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
  2074.  */
  2075. static void smooth_8R8G8B_z_triangle( GLcontext *ctx,
  2076.                                          GLuint v0, GLuint v1, GLuint v2,
  2077.                                          GLuint pv )
  2078. {
  2079.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2080. #define INTERP_Z 1
  2081. #define INTERP_RGB 1
  2082. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  2083. #define PIXEL_TYPE GLuint
  2084. //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2085. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2086. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  2087. {                                    \
  2088.    GLint i, len = RIGHT-LEFT;                        \
  2089.    for (i=0;i<len;i++) {                        \
  2090.       GLdepth z = FixedToDepth(ffz);                    \
  2091.       if (z < zRow[i]) {                        \
  2092.          pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg),    \
  2093.                  FixedToInt(ffb) );            \
  2094.          zRow[i] = z;                            \
  2095.       }                                    \
  2096.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  2097.       ffz += fdzdx;                            \
  2098.    }                                    \
  2099. }
  2100. #include "tritemp.h"
  2101. }
  2102.  
  2103.  
  2104.  
  2105. /*
  2106.  * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
  2107.  */
  2108. static void smooth_5R6G5B_z_triangle( GLcontext *ctx,
  2109.                                          GLuint v0, GLuint v1, GLuint v2,
  2110.                                          GLuint pv )
  2111. {
  2112.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2113. #define INTERP_Z 1
  2114. #define INTERP_RGB 1
  2115. #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
  2116. #define PIXEL_TYPE GLushort
  2117. //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2118. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2119. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  2120. {                                    \
  2121.    GLint i, len = RIGHT-LEFT;                        \
  2122.    for (i=0;i<len;i++) {                        \
  2123.       GLdepth z = FixedToDepth(ffz);                    \
  2124.       if (z < zRow[i]) {                        \
  2125.          pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg),    \
  2126.                  FixedToInt(ffb) );            \
  2127.          zRow[i] = z;                            \
  2128.       }                                    \
  2129.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  2130.       ffz += fdzdx;                            \
  2131.    }                                    \
  2132. }
  2133. #include "tritemp.h"
  2134. }
  2135.  
  2136. /*
  2137.  * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
  2138.  */
  2139. static void flat_8A8B8G8R_z_triangle( GLcontext *ctx, GLuint v0,
  2140.                                   GLuint v1, GLuint v2, GLuint pv )
  2141. {
  2142.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2143. #define INTERP_Z 1
  2144. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  2145. #define PIXEL_TYPE GLuint
  2146. //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2147. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2148. #define SETUP_CODE                    \
  2149.    unsigned long p = PACK_8B8G8R( VB->Color[pv][0],    \
  2150.          VB->Color[pv][1], VB->Color[pv][2] );
  2151. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  2152. {                                    \
  2153.    GLint i, len = RIGHT-LEFT;                        \
  2154.    for (i=0;i<len;i++) {                        \
  2155.       GLdepth z = FixedToDepth(ffz);                    \
  2156.       if (z < zRow[i]) {                        \
  2157.      pRow[i] = p;                            \
  2158.          zRow[i] = z;                            \
  2159.       }                                    \
  2160.       ffz += fdzdx;                            \
  2161.    }                                    \
  2162. }
  2163. #include "tritemp.h"
  2164. }
  2165.  
  2166.  
  2167. /*
  2168.  * XImage, flat, depth-buffered, PF_8R8G8B triangle.
  2169.  */
  2170. static void flat_8R8G8B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2171.                                     GLuint v2, GLuint pv )
  2172. {
  2173.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2174. #define INTERP_Z 1
  2175. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  2176. #define PIXEL_TYPE GLuint
  2177. //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2178. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2179. #define SETUP_CODE                    \
  2180.    unsigned long p = PACK_8R8G8B( VB->Color[pv][0],    \
  2181.          VB->Color[pv][1], VB->Color[pv][2] );
  2182. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  2183. {                            \
  2184.    GLint i, len = RIGHT-LEFT;                \
  2185.    for (i=0;i<len;i++) {                \
  2186.       GLdepth z = FixedToDepth(ffz);            \
  2187.       if (z < zRow[i]) {                \
  2188.      pRow[i] = p;                    \
  2189.          zRow[i] = z;                    \
  2190.       }                            \
  2191.       ffz += fdzdx;                    \
  2192.    }                            \
  2193. }
  2194. #include "tritemp.h"
  2195. }
  2196.  
  2197.  
  2198. /*
  2199.  * XImage, flat, depth-buffered, PF_5R6G5B triangle.
  2200.  */
  2201. static void flat_5R6G5B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2202.                                     GLuint v2, GLuint pv )
  2203. {
  2204.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2205. #define INTERP_Z 1
  2206. #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
  2207. #define PIXEL_TYPE GLushort
  2208. //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2209. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2210. #define SETUP_CODE                    \
  2211.    unsigned long p = PACK_5R6G5B( VB->Color[pv][0],    \
  2212.          VB->Color[pv][1], VB->Color[pv][2] );
  2213. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  2214. {                            \
  2215.    GLint i, len = RIGHT-LEFT;                \
  2216.    for (i=0;i<len;i++) {                \
  2217.       GLdepth z = FixedToDepth(ffz);            \
  2218.       if (z < zRow[i]) {                \
  2219.      pRow[i] = p;                    \
  2220.          zRow[i] = z;                    \
  2221.       }                            \
  2222.       ffz += fdzdx;                    \
  2223.    }                            \
  2224. }
  2225. #include "tritemp.h"
  2226. }
  2227.  
  2228.  
  2229. /*
  2230.  * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
  2231.  */
  2232. static void smooth_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2233.                       GLuint v2, GLuint pv )
  2234. {
  2235.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2236. #define INTERP_RGB 1
  2237. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  2238. #define PIXEL_TYPE GLuint
  2239. //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2240. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2241. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  2242. {                                    \
  2243.    GLint xx;                                \
  2244.    PIXEL_TYPE *pixel = pRow;                        \
  2245.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                \
  2246.       *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg),        \
  2247.                 FixedToInt(ffb) );            \
  2248.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  2249.    }                                    \
  2250. }
  2251. #include "tritemp.h"
  2252. }
  2253.  
  2254.  
  2255. /*
  2256.  * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
  2257.  */
  2258. static void smooth_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2259.                                     GLuint v2, GLuint pv )
  2260. {
  2261.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2262. #define INTERP_RGB 1
  2263. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  2264. #define PIXEL_TYPE GLuint
  2265. //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2266. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2267. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  2268. {                                    \
  2269.    GLint xx;                                \
  2270.    PIXEL_TYPE *pixel = pRow;                        \
  2271.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                \
  2272.       *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg),        \
  2273.                 FixedToInt(ffb) );            \
  2274.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  2275.    }                                    \
  2276. }
  2277. #include "tritemp.h"
  2278. }
  2279.  
  2280.  
  2281. /*
  2282.  * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
  2283.  */
  2284. static void smooth_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2285.                     GLuint v2, GLuint pv )
  2286. {
  2287.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2288. #define INTERP_RGB 1
  2289. #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
  2290. #define PIXEL_TYPE GLushort
  2291. //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2292. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2293. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  2294. {                                    \
  2295.    GLint xx;                                \
  2296.    PIXEL_TYPE *pixel = pRow;                        \
  2297.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                \
  2298.       *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg),        \
  2299.                 FixedToInt(ffb) );            \
  2300.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;            \
  2301.    }                                    \
  2302. }
  2303. #include "tritemp.h"
  2304. }
  2305.  
  2306.  
  2307.  
  2308. /*
  2309.  * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
  2310.  */
  2311. static void flat_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0,
  2312.                                 GLuint v1, GLuint v2, GLuint pv )
  2313. {
  2314.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2315. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  2316. #define PIXEL_TYPE GLuint
  2317. //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2318. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2319. #define SETUP_CODE                    \
  2320.    unsigned long p = PACK_8B8G8R( VB->Color[pv][0],    \
  2321.          VB->Color[pv][1], VB->Color[pv][2] );
  2322. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  2323. {                            \
  2324.    GLint xx;                        \
  2325.    PIXEL_TYPE *pixel = pRow;                \
  2326.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {        \
  2327.       *pixel = p;                    \
  2328.    }                            \
  2329. }
  2330. #include "tritemp.h"
  2331. }
  2332.  
  2333.  
  2334. /*
  2335.  * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
  2336.  */
  2337. static void flat_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2338.                                   GLuint v2, GLuint pv )
  2339. {
  2340.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2341. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  2342. #define PIXEL_TYPE GLuint
  2343. //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2344. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2345. #define SETUP_CODE                    \
  2346.    unsigned long p = PACK_8R8G8B( VB->Color[pv][0],    \
  2347.          VB->Color[pv][1], VB->Color[pv][2] );
  2348. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  2349. {                            \
  2350.    GLint xx;                        \
  2351.    PIXEL_TYPE *pixel = pRow;                \
  2352.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {        \
  2353.       *pixel = p;                    \
  2354.    }                            \
  2355. }
  2356. #include "tritemp.h"
  2357. }
  2358.  
  2359.  
  2360. /*
  2361.  * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
  2362.  */
  2363. static void flat_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2364.                                   GLuint v2, GLuint pv )
  2365. {
  2366.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2367. #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
  2368. #define PIXEL_TYPE GLushort
  2369. //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
  2370. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2371. #define SETUP_CODE                    \
  2372.    unsigned long p = PACK_5R6G5B( VB->Color[pv][0],    \
  2373.          VB->Color[pv][1], VB->Color[pv][2] );
  2374. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  2375. {                            \
  2376.    GLint xx;                        \
  2377.    PIXEL_TYPE *pixel = pRow;                \
  2378.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {        \
  2379.       *pixel = p;                    \
  2380.    }                            \
  2381. }
  2382. #include "tritemp.h"
  2383. }
  2384.  
  2385.  
  2386. /*
  2387.  * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
  2388.  */
  2389.  
  2390. static void smooth_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2391.                                        GLuint v2, GLuint pv )
  2392. {
  2393.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2394. #define INTERP_Z 1
  2395. #define INTERP_INDEX 1
  2396. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  2397. #define PIXEL_TYPE GLubyte
  2398. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2399. #define INNER_LOOP( LEFT, RIGHT, Y )                                \
  2400. {                                                                    \
  2401.    GLint i, len = RIGHT-LEFT;                                        \
  2402.    for (i=0;i<len;i++) {                                            \
  2403.       GLdepth z = FixedToDepth(ffz);                                \
  2404.       if (z < zRow[i]) {                                            \
  2405.          pRow[i] = FixedToInt(ffi);                                    \
  2406.          zRow[i] = z;                                                \
  2407.       }                                                                \
  2408.       ffi += fdidx;                                                    \
  2409.       ffz += fdzdx;                                                    \
  2410.    }                                                                \
  2411. }
  2412.  
  2413. #include "tritemp.h"
  2414. }
  2415.  
  2416.  
  2417. /*
  2418.  * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
  2419.  */
  2420.  
  2421. static void flat_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2422.                                  GLuint v2, GLuint pv )
  2423. {
  2424.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2425. #define INTERP_Z 1
  2426. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  2427. #define PIXEL_TYPE GLubyte
  2428. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2429. #define SETUP_CODE                                                    \
  2430.    GLuint index = VB->Index[pv];                                    \
  2431.    if (!VB->MonoColor) {                                            \
  2432.       /* set the color index */                                        \
  2433.       (*ctx->Driver.Index)( ctx, index );                            \
  2434.    }
  2435. #define INNER_LOOP( LEFT, RIGHT, Y )                                \
  2436. {                                                                    \
  2437.    GLint i, len = RIGHT-LEFT;                                        \
  2438.    for (i=0;i<len;i++) {                                            \
  2439.       GLdepth z = FixedToDepth(ffz);                                \
  2440.       if (z < zRow[i]) {                                            \
  2441.          pRow[i] = index;                                            \
  2442.          zRow[i] = z;                                                \
  2443.       }                                                                \
  2444.       ffz += fdzdx;                                                    \
  2445.    }                                                                \
  2446. }
  2447. #include "tritemp.h"
  2448. }
  2449.  
  2450.  
  2451.  
  2452. /*
  2453.  * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
  2454.  */
  2455.  
  2456. static void smooth_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2457.                                      GLuint v2, GLuint pv )
  2458. {
  2459.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2460. #define INTERP_Z 1
  2461. #define INTERP_INDEX 1
  2462. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  2463. #define PIXEL_TYPE GLubyte
  2464. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2465. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  2466. {                                    \
  2467.    GLint xx;                                \
  2468.    PIXEL_TYPE *pixel = pRow;                        \
  2469.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                \
  2470.       *pixel = FixedToInt(ffi);            \
  2471.       ffi += fdidx;            \
  2472.    }                                    \
  2473. }
  2474. #include "tritemp.h"
  2475. }
  2476.  
  2477.  
  2478. /*
  2479.  * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
  2480.  */
  2481. static void flat_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2482.                                  GLuint v2, GLuint pv )
  2483. {
  2484.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2485. #define INTERP_Z 1
  2486. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  2487. #define PIXEL_TYPE GLubyte
  2488. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2489. #define SETUP_CODE                                                    \
  2490.    GLuint index = VB->Index[pv];                                    \
  2491.    if (!VB->MonoColor) {                                            \
  2492.       /* set the color index */                                        \
  2493.       (*ctx->Driver.Index)( ctx, index );                            \
  2494.    }
  2495. #define INNER_LOOP( LEFT, RIGHT, Y )            \
  2496. {                            \
  2497.    GLint xx;                        \
  2498.    PIXEL_TYPE *pixel = pRow;                \
  2499.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {        \
  2500.       *pixel = index;                    \
  2501.    }                            \
  2502. }
  2503. #include "tritemp.h"
  2504. }
  2505.  
  2506. /*
  2507.  * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
  2508.  */
  2509. static void smooth_DITHER8_z_triangle( GLcontext *ctx,
  2510.                                        GLuint v0, GLuint v1, GLuint v2,
  2511.                                        GLuint pv )
  2512. {
  2513.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2514.    DITHER_RGB_TO_8BIT_SETUP
  2515. #define INTERP_Z 1
  2516. #define INTERP_RGB 1
  2517. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  2518. #define PIXEL_TYPE GLubyte
  2519. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2520. #define INNER_LOOP( LEFT, RIGHT, Y )                                    \
  2521. {                                                                        \
  2522.    GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;                    \
  2523.    for (i=0;i<len;i++,xx++) {                                            \
  2524.       GLdepth z = FixedToDepth(ffz);                                    \
  2525.       if (z < zRow[i]) {                                                \
  2526.          DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg),            \
  2527.                                 FixedToInt(ffb), xx, yy);                \
  2528.          pRow[i] = pixelDithered;                                        \
  2529.          zRow[i] = z;                                                    \
  2530.       }                                                                    \
  2531.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                        \
  2532.       ffz += fdzdx;                                                        \
  2533.    }                                                                    \
  2534. }
  2535. #include "tritemp.h"
  2536. }
  2537.  
  2538. /*
  2539.  * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
  2540.  */
  2541. static void flat_DITHER8_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2542.                                      GLuint v2, GLuint pv )
  2543. {
  2544.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2545.    DITHER_RGB_TO_8BIT_SETUP
  2546. #define INTERP_Z 1
  2547. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  2548. #define PIXEL_TYPE GLubyte
  2549. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2550.  
  2551. #define INNER_LOOP( LEFT, RIGHT, Y )                                    \
  2552. {                                                                        \
  2553.    GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;                    \
  2554.    for (i=0;i<len;i++,xx++) {                                            \
  2555.       GLdepth z = FixedToDepth(ffz);                                    \
  2556.       if (z < zRow[i]) {                                                \
  2557.         DITHER_RGB_TO_8BIT( VB->Color[pv][0],                            \
  2558.              VB->Color[pv][1], VB->Color[pv][2], xx, yy);                \
  2559.         pRow[i] = pixelDithered;                                        \
  2560.          zRow[i] = z;                                                    \
  2561.       }                                                                    \
  2562.       ffz += fdzdx;                                                        \
  2563.    }                                                                    \
  2564. }
  2565. #include "tritemp.h"
  2566. }
  2567.  
  2568. /*
  2569.  * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
  2570.  */
  2571. static void smooth_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2572.                      GLuint v2, GLuint pv )
  2573. {
  2574.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2575.    DITHER_RGB_TO_8BIT_SETUP
  2576. #define INTERP_RGB 1
  2577. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  2578. #define PIXEL_TYPE GLubyte
  2579. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2580. #define INNER_LOOP( LEFT, RIGHT, Y )                                    \
  2581. {                                                                        \
  2582.    GLint xx, yy = FLIP(Y);                                                \
  2583.    PIXEL_TYPE *pixel = pRow;                                            \
  2584.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                                \
  2585.       DITHER_RGB_TO_8BIT( VB->Color[pv][0],    VB->Color[pv][1], VB->Color[pv][2], xx, yy);\
  2586.       *pixel = pixelDithered;                                            \
  2587.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                        \
  2588.    }                                                                    \
  2589. }
  2590. #include "tritemp.h"
  2591. }
  2592.  
  2593. /*
  2594.  * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
  2595.  */
  2596.  
  2597. static void flat_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  2598.                                    GLuint v2, GLuint pv )
  2599. {
  2600.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2601.    DITHER_RGB_TO_8BIT_SETUP
  2602. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  2603. #define PIXEL_TYPE GLubyte
  2604. #define BYTES_PER_ROW (wmesa->ScanWidth)
  2605.  
  2606. #define INNER_LOOP( LEFT, RIGHT, Y )                                    \
  2607. {                                                                        \
  2608.    GLint xx, yy = FLIP(Y);                                                \
  2609.    PIXEL_TYPE *pixel = pRow;                                            \
  2610.    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                                \
  2611.       DITHER_RGB_TO_8BIT( VB->Color[pv][0],                                \
  2612.              VB->Color[pv][1], VB->Color[pv][2], xx, yy);                \
  2613.       *pixel = pixelDithered;                                            \
  2614.    }                                                                    \
  2615. }
  2616. #include "tritemp.h"
  2617. }
  2618.  
  2619.  
  2620.  
  2621.  
  2622. static triangle_func choose_triangle_function( GLcontext *ctx )
  2623. {
  2624.    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
  2625.    int depth = wmesa->cColorBits;
  2626.  
  2627.    if (ctx->Polygon.SmoothFlag)     return NULL;
  2628.    if (ctx->Texture.Enabled)        return NULL;
  2629.    if (!wmesa->db_flag) return NULL;    
  2630.    /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
  2631.       if (   ctx->Light.ShadeModel==GL_SMOOTH
  2632.           && ctx->RasterMask==DEPTH_BIT
  2633.           && ctx->Depth.Func==GL_LESS
  2634.           && ctx->Depth.Mask==GL_TRUE
  2635.           && ctx->Polygon.StippleFlag==GL_FALSE) {
  2636.          switch (wmesa->pixelformat) {
  2637.             case PF_8A8B8G8R:
  2638.                return smooth_8A8B8G8R_z_triangle;
  2639.             case PF_8R8G8B:
  2640.                return smooth_8R8G8B_z_triangle;
  2641.             case PF_5R6G5B:
  2642.                return smooth_5R6G5B_z_triangle;
  2643.             case PF_DITHER8:
  2644.                return  smooth_DITHER8_z_triangle;
  2645.             case PF_INDEX8:
  2646.                return smooth_ci_z_triangle;
  2647.             default:
  2648.                return NULL;
  2649.          }
  2650.       }
  2651.       if (   ctx->Light.ShadeModel==GL_FLAT
  2652.           && ctx->RasterMask==DEPTH_BIT
  2653.           && ctx->Depth.Func==GL_LESS
  2654.           && ctx->Depth.Mask==GL_TRUE
  2655.           && ctx->Polygon.StippleFlag==GL_FALSE) {
  2656.          switch (wmesa->pixelformat) {
  2657.             case PF_8A8B8G8R:
  2658.                return flat_8A8B8G8R_z_triangle;
  2659.             case PF_8R8G8B:
  2660.                return flat_8R8G8B_z_triangle;
  2661.             case PF_5R6G5B:
  2662.                return flat_5R6G5B_z_triangle;
  2663.             case PF_DITHER8:
  2664.                return flat_DITHER8_z_triangle;
  2665.             case PF_INDEX8:
  2666.                return flat_ci_z_triangle;
  2667.             default:
  2668.                return NULL;
  2669.          }
  2670.       }
  2671.       if (   ctx->RasterMask==0   /* no depth test */
  2672.           && ctx->Light.ShadeModel==GL_SMOOTH
  2673.           && ctx->Polygon.StippleFlag==GL_FALSE) {
  2674.          switch (wmesa->pixelformat) {
  2675.             case PF_8A8B8G8R:
  2676.                return smooth_8A8B8G8R_triangle;
  2677.             case PF_8R8G8B:
  2678.                return smooth_8R8G8B_triangle;
  2679.             case PF_5R6G5B:
  2680.                return smooth_5R6G5B_triangle;
  2681.             case PF_DITHER8:
  2682.                return smooth_DITHER8_triangle;
  2683.             case PF_INDEX8:
  2684.                return smooth_ci_triangle;
  2685.             default:
  2686.                return NULL;
  2687.          }
  2688.       }
  2689.  
  2690.       if (   ctx->RasterMask==0   /* no depth test */
  2691.           && ctx->Light.ShadeModel==GL_FLAT
  2692.           && ctx->Polygon.StippleFlag==GL_FALSE) {
  2693.          switch (wmesa->pixelformat) {
  2694.             case PF_8A8B8G8R:
  2695.                return flat_8A8B8G8R_triangle;
  2696.             case PF_8R8G8B:
  2697.                return flat_8R8G8B_triangle;
  2698.             case PF_5R6G5B:
  2699.                return flat_5R6G5B_triangle;
  2700.             case PF_DITHER8:
  2701.                return flat_DITHER8_triangle;
  2702.             case PF_INDEX8:
  2703.                return flat_ci_triangle;
  2704.             default:
  2705.                return NULL;
  2706.          }
  2707.       }
  2708.  
  2709.       return NULL;
  2710.    }
  2711. }
  2712.  
  2713. /*
  2714.  * Define a new viewport and reallocate auxillary buffers if the size of
  2715.  * the window (color buffer) has changed.
  2716.  */
  2717. void WMesaViewport( GLcontext *ctx,
  2718.                   GLint x, GLint y, GLsizei width, GLsizei height )
  2719. {
  2720.    /* Save viewport */
  2721.    ctx->Viewport.X = x;
  2722.    ctx->Viewport.Width = width;
  2723.    ctx->Viewport.Y = y;
  2724.    ctx->Viewport.Height = height;
  2725.  
  2726.    /* compute scale and bias values */
  2727.    ctx->Viewport.Sx = (GLfloat) width / 2.0F;
  2728.    ctx->Viewport.Tx = ctx->Viewport.Sx + x;
  2729.    ctx->Viewport.Sy = (GLfloat) height / 2.0F;
  2730.    ctx->Viewport.Ty = ctx->Viewport.Sy + y;
  2731. }
  2732.  
  2733.